package com.slipper.core.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;

public class ThreadUtil {
    private static final Logger logger = LoggerFactory.getLogger(ThreadUtil.class);

    private static final Object lock = new Object();
    private static boolean isMonitor = false;
    private static Timer timer;
    private static ThreadPoolExecutor executor;

    static {
        init();
    }

    public static synchronized void init() {
        if (executor != null) {
            executor.shutdownNow();
        }

        executor = new ThreadPoolExecutor(
                0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<>());
    }

    public static void execute(Runnable command) {
        executor.execute(command);
        startMonitor();
    }

    public static Future<?> submit(Runnable task) {
        Future<?> future = executor.submit(task);
        startMonitor();
        return future;
    }

    private static void startMonitor() {
        if (ThreadUtil.isMonitor) return;

        synchronized(ThreadUtil.lock) {
            if (ThreadUtil.isMonitor) return;
            ThreadUtil.isMonitor = true;
            ThreadUtil.timer = new Timer();
            ThreadUtil.timer.schedule(createTask(), 0, 10 * 60 * 1000L);
        }
    }

    private static void stopMonitor() {
        synchronized(ThreadUtil.lock) {
            ThreadUtil.timer.cancel();
            ThreadUtil.timer = null;
            ThreadUtil.isMonitor = false;
        }
    }

    private static TimerTask createTask() {
        return new TimerTask() {
            @Override
            public void run() {
                logger.info("总任务数：{}, 已执行任务数：{}, 排队中任务数：{}, 执行中任务数：{}",
                        ThreadUtil.executor.getTaskCount(),
                        ThreadUtil.executor.getCompletedTaskCount(),
                        ThreadUtil.executor.getQueue().size(),
                        ThreadUtil.executor.getActiveCount());
                if (ThreadUtil.executor.getQueue().isEmpty() && executor.getActiveCount() == 0) {
                    stopMonitor();
                }
            }
        };
    }
}
